/*
 * Created on 16.04.2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package pho.prowon.index;

/**
 * @author Peter
 *
 * The IndexFactory is a singleton used to get an instance of a class
 * implementing the IndexImplementation interface
 * The class that should be instantiated is retrieved from the system
 * property 'pho.prowon.IndexImplementation'. If the property is not 
 * present, the default implementation 'pho.prowon.index.IndexXMLImplementation'
 * is used.
 * Once an instance of an IndexImplementation has been created, it is cached and
 * will be reused on every call for an instance
 */
public class IndexFactory
{
	private static final String INDEX_IMPLEMENTATION_PROPERTY = "prowon.IndexImplementation";
	private static IndexImplementation _instance = null;

	private IndexFactory()
	{
	}

	/**
	 * This factory method returns an instance of IndexImplementation
	 * @return an instance of a class implementing IndexImplementation interface
	 * @throws ClassNotFoundException
	 */
	public static IndexImplementation getIndexImplementation()
		throws ClassNotFoundException
	{
		String fallbackClassName = "pho.prowon.index.IndexXMLImplementationDOM";

		if (_instance == null)
		{
			// Use the system property first
			String systemProp = System.getProperty(INDEX_IMPLEMENTATION_PROPERTY);
			if (systemProp != null)
			{
				_instance = newInstance(systemProp);
				// @PHO What shall we return if _instance == null...?
				return _instance;
			}

			if (fallbackClassName == null)
			{
				throw new ClassNotFoundException(
					"Provider for " + INDEX_IMPLEMENTATION_PROPERTY + " cannot be found",
					null);
			}

			System.out.println("loaded from fallback value: " + fallbackClassName);
			_instance = newInstance(fallbackClassName);
			// @PHO What shall we return if _instance == null...?
		}
		return _instance;

	}

	private static IndexImplementation newInstance(String className)
		throws ClassNotFoundException
	{
		Class spiClass;
		spiClass = Class.forName(className);

		Class[] interfaces = spiClass.getInterfaces();
		for (int i = 0; i < interfaces.length; i++)
		{
			if (interfaces[i]
				.getName()
				.equals("pho.prowon.index.IndexImplementation"))
			{
				try
				{
					return (IndexImplementation) spiClass.newInstance();
				}
				catch (InstantiationException e)
				{
					System.out.println (e.getMessage());
				}
				catch (IllegalAccessException e)
				{
					System.out.println (e.getMessage());
				}
			}
		}
		return null;
	}
}
